<?php
require_once LIBS_DIR . 'classes/class.DataSource.php'; //LIBS_DIR is defined in config.php

class Table extends DataSource
{
	public $fields = array();
	public $field_names = array();
	public $hierarch = FALSE; // tells if table has field 'parent'
	public $table = NULL; // table name
	
	public function __construct($table)
	{
		parent::__construct();
		$this->table = $this->dbprefix . $table;
		$this->get_fields();
	}

	//Sets relations for fields (in case you want to get in select result 'status' = ON instead of 'status' = 1). Put argument in this way:
	// 	array(
	// 			'category_id' (field of the current table)	=> array('category' (related table), 'id' (related field), 'name' (field you want to get in related table)),
	// 			'status'	=> array('product_status', 'id', 'name'))
	public function set_relations($relations = array())
	{
		foreach ($relations as $field => $rel)
		{
			$field_key = array_search($field, $this->field_names);
			if ($field_key !== FALSE){
				$this->relations[$field_key] = $rel;
			}
		}
	}
	
	function add_table_name($field)
	{
		return "`$this->table`.`$field`";
	}
	
	//where argument should be:
	//							 array(
	// 								array('category_id', 6, '='),
	// 								array('status', 1, '!='))
	// or just string like: " `$category->table`.`status` = 'ON' "
	public function select($where = '', $fields = '',  $orderby = array() )
	{
		//Added sorting by 'parent' and 'order' fields if they exist in current table
		$orderby[] = in_array('parent', $this->field_names) ? 'parent' : '';
		$orderby[] = in_array('order', $this->field_names) ? 'order' : '';
		foreach ($orderby as $order)
		{
			if (!empty($order)){
			$orderbyit[] = $this->add_table_name($order);
			}
		}
		$orderby = !empty($orderbyit) ? join(', ', $orderbyit) : '';

		if (!empty($fields) && !preg_match('|*|',$fields)) {
			$relfields[] = $fields;
		}
		
		if (!empty($where)) 
		{
			if (is_array($where)){
			foreach ($where as $where_item)
			{
				if(!is_numeric($where_item[1])){
					$where_item[1] = "'" .dbsafe($where_item[1]). "'";
				}
				$relwhere[] = " `$this->table`.`$where_item[0]` $where_item[2] $where_item[1]";
			}
			}
			else{
				$relwhere[] = $where;
			}
		}
		
		$from[] = $this->table; 
		
		foreach ($this->field_names as $field_key => $field_name)
		{
			if (!empty($this->relations[$field_key])){
				$relfields[] = " `$this->dbprefix{$this->relations[$field_key][0]}`.`{$this->relations[$field_key][2]}` as '$field_name'";
				$relwhere[] = " `$this->dbprefix{$this->relations[$field_key][0]}`.`{$this->relations[$field_key][1]}` = `$this->table`.`$field_name`";
				$from[] = " `$this->dbprefix{$this->relations[$field_key][0]}`";
			}
			else {
				$relfields[] = " `$this->table`.`$field_name` as '$field_name'";
			}
		}
		$fields = !empty($relfields) ? join(', ', $relfields) : ' * ';
		$where = !empty($relwhere) ? join(' AND ', $relwhere) : ' 1 ';
		$from = !empty($from) ? join(', ', $from) : $this->table;
		
		return parent::select($from, $where, $fields, $orderby);
	}
	
	public function __destruct()
	{
		parent::__destruct();
	}

	

	private function get_fields()// write to the $fields the structure of table
	{
		$this->sql_query("SHOW columns FROM  `$this->table`");
		while ($row = $this->next())
		{
			if (preg_match("|enum\((.*)\)|", $row['Type'], $match))
			{
				$finalResult = array();
				$opts = explode(',', $match[1]);
				foreach ($opts as $item){
					$finalResult[] = substr($item, 1, strlen($item)-2);
				}
				$row['Enum'] = $finalResult;
				$row['Type'] = 'enum';
			}
	
			if (preg_match("|([a-z]+)\(([\d]*)\)|", $row['Type'], $match))
			{
				$row['Lenth'] = $match[2];
				$row['Type'] = $match[1];
			}
			$this->field_names[] = $row['Field'];
			$this->fields[] = $row ;
		};
		$this->hierarch = in_array('parent', $this->field_names) ? TRUE : FALSE;
	}
}
?>